home *** CD-ROM | disk | FTP | other *** search
- /* AOMPanelEvent.c */
- /*
- * AddressOMatic Sample
- * AOMPanelEvent.c
- * Copyright © 1993 Apple Computer Inc. All rights reserved.
- */
- #include "AddressOMaticPrivate.h"
- #include <OCEStandardMail.h>
- enum { /* Keyboard commands */
- NUL = 0, /* NUL == EOS */
- charEnter = 0x03, /* Enter key */
- charTab = '\t', /* Tab key */
- charReturn = 0x1D, /* Return key */
- charEscape = 0x1B /* Stop key */
- };
-
- OSErr _AOMMouseEvent(
- register AddressOMaticPtr aomPtr,
- const EventRecord *theEvent,
- register AOMPanelState *whatHappened
- );
- AOMModeBit _AOMTrackRadioButton(
- AddressOMaticPtr aomPtr,
- Point mousePt,
- short index
- );
- AOMPanelState _AOMDoToButtonHit(
- AddressOMaticPtr aomPtr,
- Boolean isButtonHit
- );
- AOMPanelState _AOMDoEnterKey(
- AddressOMaticPtr aomPtr
- );
- /*
- * Call on every event (even update events)
- */
- pascal OSErr
- AOMPanelEvent(
- AddressOMaticPtr aomPtr, /* The panel */
- const EventRecord *theEvent, /* The event */
- register AOMPanelState *whatHappened /* Result */
- )
- {
- OSErr status;
- WindowPtr theWindow;
- Boolean isActivating;
- SDPPanelState panelState;
- SDPFindPanelResult findResult;
- unsigned short theChar;
- SDPPanelHandle thePanel;
- short eventWhat;
- Boolean findWasFinding;
- AOMSaveState saveState;
-
- #define EVENT (*theEvent)
- #define STATE (*whatHappened)
-
- STATE = kAOMAppMustHandleEventMask;
- status = noErr;
- /*
- * Since theEvent is a const, we can't set theEvent->what
- * to skip events. This is a hack.
- */
- eventWhat = EVENT.what;
- /*
- * TBS: Call the SDP Browse and Find event handlers
- * and merge their state values into the STATE variable.
- * Clear kAOMAppMustHandleEventBit if the SDP routines
- * handled the event. The following is needed only if
- * we must handle the event.
- * NOTE: Do not pass an update event to the
- * SDP Panel Event function. Pass mouse events only
- * if in the panel itself.
- */
- if ((EVENT.modifiers & optionKey) != AOM.optKeyDown) {
- AOM.optKeyDown = EVENT.modifiers & optionKey;
- AOM.buttonUpdateNeeded = TRUE;
- }
- if (eventWhat != updateEvt && eventWhat != mouseDown) {
- if (eventWhat != nullEvent)
- AOM.buttonUpdateNeeded = TRUE;
- switch (AOM.currentMode) {
- case kAOMEnablePDBit:
- thePanel = AOM.pdPanel;
- goto panelEvent;
- case kAOMEnablePanelBit:
- thePanel = AOM.browsePanel;
- panelEvent: _AOMSaveState(aomPtr, kAOMTextFontStyle, &saveState);
- status = SDPPanelEvent(thePanel, theEvent, &panelState);
- _AOMRestoreState(&saveState);
- LOG(status, "\pSDPPanelEvent");
- if (status == noErr && panelState == kSDPSelectedAnItem) {
- STATE |= kAOMSelectedAnItemMask;
- _AOMFlashButton(aomPtr, AOM.toButton);
- STATE |= (AOM.optKeyDown)
- ? kAOMSaveButtonHitMask
- : kAOMToButtonHitMask;
- }
- break;
- case kAOMEnableFindBit:
- findWasFinding = FINDING;
- _AOMSaveState(aomPtr, kAOMTextFontStyle, &saveState);
- status = SDPFindPanelEvent(AOM.findPanel, theEvent, &findResult);
- _AOMRestoreState(&saveState);
- LOG(status, "\pSDPFindPanelEvent");
- /*
- * Hack: if the user types <Return> or <Enter>, and there is text to be
- * found, the FindPanel starts or stops up immediately. This confuses
- * our own logic. We test for this condition and force the event
- * to "null event" in this case.
- */
- if (status == noErr
- && (eventWhat == keyDown || eventWhat == autoKey)) {
- theChar = EVENT.message & charCodeMask;
- if (theChar == charReturn || theChar == charEnter) {
- /*
- * The user hit "enter" key. Don't process it in the next
- * section. _AOMFlashButton will fix the button state.
- */
- eventWhat = nullEvent;
- _AOMFlashButton(aomPtr, AOM.toButton);
- }
- }
- if (status == noErr && findResult != 0) {
- if (findResult == kSDPSelectedAFindItem) {
- STATE |= kAOMSelectedAnItemMask;
- _AOMFlashButton(aomPtr, AOM.toButton);
- STATE |= (AOM.optKeyDown)
- ? kAOMSaveButtonHitMask
- : kAOMToButtonHitMask;
- }
- }
- break;
- #ifdef ENABLE_TYPEIN
- case kAOMEnableTypeInBit:
- status = _AOMTypeInEvent(aomPtr, theEvent, whatHappened);
- LOG(status, "\p_AOMTypeInEvent");
- break;
- #endif
- }
- }
- if (status == noErr) {
- switch (eventWhat) {
- case nullEvent:
- break;
- case keyDown:
- case autoKey:
- theChar = EVENT.message & charCodeMask;
- /*
- * TBS: use the "approved" test for <CMD><PERIOD>.
- */
- if (theChar == '.' && (EVENT.modifiers & cmdKey) != 0) {
- /*
- * TBS: Stop Find, Stop Browse, Stop spinning.
- */
- AOM.buttonUpdateNeeded = TRUE;
- }
- else if (theChar == charTab) {
- /* TBS */
- }
- else if (theChar == charReturn || theChar == charEnter)
- STATE = _AOMDoEnterKey(aomPtr);
- else {
- /* Nothing (Type-in did it's thing already) */
- }
- break;
- case mouseDown:
- status = _AOMMouseEvent(aomPtr, theEvent, whatHappened);
- break;
- case updateEvt:
- break;
- case activateEvt:
- theWindow = (WindowPtr) EVENT.message;
- isActivating = ((EVENT.modifiers & activeFlag) != 0);
- goto activateEvent;
- break;
- case osEvt:
- switch (((unsigned long) EVENT.message) >> 24) {
- case mouseMovedMessage:
- break;
- case suspendResumeMessage:
- isActivating = ((EVENT.message & 0x01) != 0);
- theWindow = FrontWindow();
- activateEvent: if (theWindow == AOM.window) {
- /*
- * The SDP and Type-in handlers did the work
- */
- }
- break;
- }
- break;
- }
- }
- if (AOM.buttonUpdateNeeded)
- _AOMSetButtonText(aomPtr);
- if (FINDING)
- STATE |= kAOMFindInProgressMask;
- LOG(status, "\pAOMPanelEvent exit");
- return (status);
- #undef EVENT
- #undef STATE
- }
-
- OSErr
- _AOMMouseEvent(
- register AddressOMaticPtr aomPtr,
- const EventRecord *theEvent,
- register AOMPanelState *whatHappened
- )
- {
- OSErr status;
- WindowPtr theWindow;
- AOMSaveState saveState;
- Boolean clickInPanel;
- short partCode;
- Point mousePt;
- ControlHandle theControl;
- short i;
- AOMModeBit newMode;
- SDPPanelState panelState;
- SDPFindPanelResult findResult;
- SDPPanelHandle thePanel;
- #define EVENT (*theEvent)
- #define STATE (*whatHappened)
-
- status = noErr;
- /*
- * TBS: if the mouse point is outside the AOM Panel,
- * and we were the target, set the "AppBecomesTarget" bit.
- * If inside the AOM panel (and we weren't the target), set
- * the "PanelBecomesTarget" bit). We should track the
- * AppleLetter logic here.
- */
- partCode = FindWindow(EVENT.where, &theWindow);
- if (theWindow == AOM.window) {
- _AOMSaveState(aomPtr, kAOMLabelFontStyle, &saveState);
- mousePt = EVENT.where;
- GlobalToLocal(&mousePt);
- clickInPanel = PtInRect(mousePt, &BOUNDS);
- if (AOM.isTarget && clickInPanel == FALSE)
- STATE |= kAOMAppBecomesTargetMask;
- else if (AOM.isTarget == FALSE && clickInPanel)
- STATE |= kAOMPanelBecomesTargetMask;
- AOM.isTarget = clickInPanel;
- if (clickInPanel) {
- /*
- * Click in our panel. Check for a button.
- * Note that we handle these events.
- */
- if (PtInRect(mousePt, &PANEL)) {
- switch (AOM.currentMode) {
- case kAOMEnablePDBit:
- thePanel = AOM.pdPanel;
- goto clickInPanel;
- break;
- case kAOMEnablePanelBit:
- thePanel = AOM.browsePanel;
- clickInPanel: status = _AOMPanelSetFocus(aomPtr, thePanel, TRUE);
- status = SDPPanelEvent(thePanel, theEvent, &panelState);
- LOG(status, "\pSDPPanelEvent");
- if (status == noErr && panelState == kSDPSelectedAnItem) {
- STATE |= kAOMSelectedAnItemMask;
- _AOMFlashButton(aomPtr, AOM.toButton);
- STATE |= (AOM.optKeyDown)
- ? kAOMBCCButtonHitMask
- : kAOMCCButtonHitMask;
- }
- break;
- case kAOMEnableFindBit:
- status = SDPFindPanelEvent(AOM.findPanel, theEvent, &findResult);
- LOG(status, "\pSDPFindPanelEvent");
- if (status == noErr && findResult != 0) {
- if (findResult == kSDPSelectedAFindItem) {
- STATE |= kAOMSelectedAnItemMask;
- _AOMFlashButton(aomPtr, AOM.toButton);
- STATE |= (AOM.optKeyDown)
- ? kAOMBCCButtonHitMask
- : kAOMCCButtonHitMask;
- }
- }
- break;
- #ifdef ENABLE_TYPEIN
- case kAOMEnableTypeInBit:
- status = _AOMTypeInEvent(aomPtr, theEvent, whatHappened);
- LOG(status, "\p_AOMTypeInEvent");
- break;
- #endif
- }
- STATE &= ~kAOMAppMustHandleEventMask;
- }
- else if (partCode == inContent) {
- partCode = FindControl(mousePt, theWindow, &theControl);
- if (partCode == inButton) {
- partCode = TrackControl(theControl, mousePt, NULL);
- if (partCode != 0) {
- /*
- * User clicked on a button. Return the
- * button state.
- */
- if (theControl == AOM.doneButton)
- STATE |= kAOMDoneButtonHitMask;
- else if (theControl == AOM.ccButton
- && ControlEnabled(AOM.ccButton)) {
- STATE |=
- (AOM.optKeyDown)
- ? kAOMBCCButtonHitMask
- : kAOMCCButtonHitMask;
- }
- else if (theControl == AOM.toButton
- && ControlEnabled(AOM.toButton)) {
- STATE |= _AOMDoToButtonHit(aomPtr, TRUE);
- }
- STATE &= ~kAOMAppMustHandleEventMask;
- } /* If button click */
- } /* In an action button */
- else { /* Not in an action button */
- /*
- * Check for a radio "button." These are implemented
- * as "hotRects" -- we do the TrackControl here.
- */
- newMode = AOM.currentMode;
- for (i = 0; i < kAOMRadioButtons; i++) {
- if (PtInRect(mousePt, &RADIO(i))) {
- newMode = _AOMTrackRadioButton(aomPtr, mousePt, i);
- break;
- }
- }
- if (newMode != AOM.currentMode)
- _AOMSelectMode(aomPtr, newMode);
- } /* Not in an action button */
- } /* In panel content */
- } /* Click in AOM panel */
- _AOMRestoreState(&saveState);
- } /* Click in our window */
- LOG(status, "\p_AOMMouseEvent");
- return (status);
- #undef EVENT
- #undef STATE
- }
-
- /*
- * The mouse hit one of our radio buttons. If it's already selected,
- * just ignore it. Else, track the button. If the user selects the
- * new button, return the new mode.
- */
- AOMModeBit
- _AOMTrackRadioButton(
- register AddressOMaticPtr aomPtr,
- Point mousePt,
- short index
- )
- {
- register AOMRadioButtonPtr buttonPtr;
- Rect hitRect;
- Boolean inHitRect;
- Boolean newInHitRect;
- short i;
- AOMModeBit newMode;
-
- #define BUTTON (*buttonPtr)
-
- newMode = AOM.currentMode;
- buttonPtr = (AOMRadioButtonPtr) &_AOMRadioInfo[index];
- if (BUTTON.modeBit == AOM.currentMode
- || AOM.radioEnable[index] == FALSE) {
- /*
- * Do nothing if this is the currently-selected radio button
- * or if this button is disabled.
- */
- }
- else {
- /*
- * Track the button.
- */
- hitRect = RADIO(index);
- _AOMPlotIcon(aomPtr, index, TRUE);
- inHitRect = TRUE;
- if (StillDown()) {
- while (WaitMouseUp()) {
- GetMouse(&mousePt);
- newInHitRect = PtInRect(mousePt, &hitRect);
- if (newInHitRect != inHitRect) {
- /*
- * The mouse moved in or out of the button.
- */
- inHitRect = newInHitRect;
- _AOMPlotIcon(aomPtr, index, inHitRect);
- }
- }
- }
- if (inHitRect) {
- /*
- * Now, find the previously selected radio button and deselect it.
- */
- for (i = 0; i < kAOMRadioButtons; i++) {
- if (_AOMRadioInfo[i].modeBit == AOM.currentMode) {
- _AOMPlotIcon(aomPtr, i, FALSE);
- break; /* Found it, exit now */
- } /* Found the radio button */
- } /* For all radio buttons */
- newMode = _AOMRadioInfo[index].modeBit; /* New selection */
- } /* User chose a new button */
- } /* It's a selectable button */
- return (newMode);
- #undef BUTTON
- }
-
-
- /*
- * Switch from AOM.currentMode to AOM.newMode
- */
- void
- _AOMSelectMode(
- register AddressOMaticPtr aomPtr,
- AOMModeBit newMode
- )
- {
- SDPPanelHandle thePanel;
-
- if (AOM.currentMode != newMode) {
- AOM.buttonUpdateNeeded = TRUE; /* Check buttons */
- switch (AOM.currentMode) { /* Disable previous */
- case kAOMEnablePDBit:
- thePanel = AOM.pdPanel;
- goto deselectPanel;
- break;
- case kAOMEnablePanelBit:
- thePanel = AOM.browsePanel;
- deselectPanel: (void) _AOMPanelShow(aomPtr, thePanel, FALSE);
- (void) _AOMPanelSetFocus(aomPtr, thePanel, FALSE);
- (void) _AOMPanelEnable(aomPtr, thePanel, FALSE);
- break;
- case kAOMEnableFindBit:
- (void) _AOMFindShow(aomPtr, FALSE);
- (void) _AOMFindStartStop(aomPtr, FALSE); /* Stop finding */
- (void) _AOMFindEnable(aomPtr, FALSE);
- break;
- #ifdef ENABLE_TYPEIN
- case kAOMEnableTypeInBit:
- (void) _AOMTypeInShow(aomPtr, FALSE);
- break;
- #endif
- }
- EraseRect(&EXTERIOR);
- AOM.currentMode = newMode;
- switch (newMode) { /* Enable new */
- case kAOMEnablePDBit:
- thePanel = AOM.pdPanel;
- goto selectPanel;
- break;
- case kAOMEnablePanelBit:
- thePanel = AOM.browsePanel;
- selectPanel: (void) _AOMPanelEnable(aomPtr, thePanel, TRUE);
- (void) _AOMPanelSetFocus(aomPtr, thePanel, TRUE);
- (void) _AOMPanelShow(aomPtr, thePanel, TRUE);
- break;
- case kAOMEnableFindBit:
- (void) _AOMFindEnable(aomPtr, TRUE); /* Enable find */
- (void) _AOMFindShow(aomPtr, TRUE); /* Show find */
- break;
- #ifdef ENABLE_TYPEIN
- case kAOMEnableTypeInBit:
- (void) _AOMTypeInShow(aomPtr, TRUE);
- break;
- #endif
- }
- _AOMDrawTitleString(aomPtr);
- }
- }
-
- /*
- * The user hit the Enter or Return key. If the "To" button
- * is enabled, treat it as a hit in the "To" button, else, it's
- * the caller's responsibility.
- */
- AOMPanelState
- _AOMDoEnterKey(
- register AddressOMaticPtr aomPtr
- )
- {
- if (AOM.toButton == NULL
- || (**AOM.toButton).contrlHilite == kInactiveControl)
- {
- return (kAOMAppMustHandleEventMask);
- }
- else {
- _AOMFlashButton(aomPtr, AOM.toButton);
- return (_AOMDoToButtonHit(aomPtr, FALSE));
- }
- }
-
- /*
- * The user clicked in the "To" button. If we are in the find
- * panel, this may be a request to Start or Stop the find process.
- */
- AOMPanelState
- _AOMDoToButtonHit(
- register AddressOMaticPtr aomPtr,
- Boolean isButtonHit
- )
- {
- AOMPanelState result;
- SDPFindPanelState findState;
- SDPSelectionState selectionState;
- SDPPanelState whatHappened;
- OSErr status;
- SDPPanelHandle thePanel;
-
- result = 0;
- AOM.buttonUpdateNeeded = TRUE;
- switch (AOM.currentMode) {
- case kAOMEnablePDBit:
- thePanel = AOM.pdPanel;
- goto hitPanel;
- case kAOMEnablePanelBit:
- thePanel = AOM.browsePanel;
- hitPanel: /*
- * If a container is chosen, open it, else return
- * the "to button hit" to the user.
- */
- status = SDPGetPanelSelectionState(
- thePanel,
- &selectionState
- );
- if (status == noErr) {
- switch (selectionState) {
- default:
- case kSDPNothingSelected:
- case kSDPLockedContainerSelected:
- break;
- case kSDPContainerAliasSelected:
- case kSDPContainerSelected:
- status = SDPOpenSelectedItem(
- thePanel,
- &whatHappened
- );
- break;
- case kSDPRecordSelected:
- case kSDPRecordAliasSelected:
- if (isButtonHit
- || whatHappened == kSDPSelectedAnItem
- || whatHappened == kSDPChangedSelection) {
- if (isButtonHit == FALSE)
- _AOMFlashButton(aomPtr, AOM.toButton);
- result = (AOM.optKeyDown)
- ? kAOMSaveButtonHitMask
- : kAOMToButtonHitMask;
- result |= (whatHappened == kSDPSelectedAnItem)
- ? kAOMSelectedAnItemMask
- : kAOMChangedSelectionMask;
- }
- break;
- }
- }
- break;
- case kAOMEnableFindBit:
- status = SDPGetFindPanelState(AOM.findPanel, &findState);
- LOG(status, "\pSDPGetFindPanelState");
- if (FINDING) {
- _AOMFindStartStop(aomPtr, FALSE);
- result = 0;
- }
- else if ((findState & kSDPItemIsSelectedMask) != 0) {
- result = (AOM.optKeyDown)
- ? kAOMSaveButtonHitMask
- : kAOMToButtonHitMask;
- }
- else if ((findState & kSDPFindTextExistsMask) != 0) {
- _AOMFindStartStop(aomPtr, TRUE);
- result = 0;
- }
- else {
- result = 0;
- }
- break;
- #ifdef ENABLE_TYPEIN
- case kAOMEnableTypeInBit:
- result = (AOM.optKeyDown)
- ? kAOMSaveButtonHitMask
- : kAOMToButtonHitMask;
- break;
- #endif
- }
- return (result);
- }
-
- /*
- * Flash the "To" button. Note: this always updated the button text.
- */
- void
- _AOMFlashButton(
- register AddressOMaticPtr aomPtr,
- ControlHandle theControl
- )
- {
- #pragma unused (aomPtr)
- long finalTicks;
- AOMSaveState saveState;
-
- /*
- * theControl will be NULL if the user forgot to
- * create one.
- */
- _AOMSetButtonText(aomPtr);
- if (theControl != NULL) {
- _AOMSaveState(aomPtr, kAOMLabelFontStyle, &saveState);
- HiliteControl(theControl, inButton);
- Delay(8, &finalTicks);
- HiliteControl(theControl, 0);
- _AOMRestoreState(&saveState);
- }
- }
-